﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Xml.Serialization;     // Added to use serialisation
using System.IO;                    // Added to use serialisation to file
using System.Net;                   // To be able to do httpresuest to download image...
using TheMovieDB;
//using TvdbLib;
//using TvdbLib.Data;

namespace WDTVMetadata
{
    class WDTVLiveHubMetadataLoader
    {
        public const string DefaultExtensions = ".AVI, .XVID, .AVC, .MPEG, .MPG, .VOB, .MKV, .TS, .TP, .M2T, .MP4, .MOV, .M2TS, .WMV, .ISO";
        public string LoggingFile { get; set; }
        // public Hashtable Extensions { get; set; }
        public string[] Extensions { get; set; }
        public string[] TermsToExclude { get; set; }
        public bool IncludeSubdirs { get; set; }
        public bool ForceReload { get; set; }

        public enum sourcesToUse
        {
            movieDb = 0,
            tvDb = 1,
            movieDbTHENtvDb = 2,
            tvDbTHENmovieDb = 3
        }
        
        public WDTVLiveHubMetadataLoader()
        {
            LoggingFile = "c:\\temp\\WDTVMetadataLoader.log";
//            Extensions = Helper.extensionsCommaseperatedToHashtable(DefaultExtensions);
            IncludeSubdirs = true;
            ForceReload = false;
        }

        public void loadMetadata(string dir)
        {
            WriteLogging("[START     ] " + DateTime.Now);

            foreach (string f in Directory.GetFiles(dir))
            {
                loadMetadataForFile(f);
            }

            if (IncludeSubdirs == true)
                loadMetadataRecursive(dir);
        }

        private void loadMetadataRecursive(string dir)
        {
            foreach (string d in Directory.GetDirectories(dir))
            {
                foreach (string f in Directory.GetFiles(d))
                {
                    loadMetadataForFile(f);
                }
                loadMetadataRecursive(d);
            }
        }

        private void loadMetadataForFile(string file)
        {
            string extension = Path.GetExtension(file);

            // If the extension of the file isn't in the list of extensions to treat... return!
            if (!Extensions.Contains(extension.ToLowerInvariant()))
                return;

            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
            string fileNameXML = Path.GetDirectoryName(file) + "\\" + fileNameWithoutExtension + ".xml";
            string fileNameJPG = Path.GetDirectoryName(file) + "\\" + fileNameWithoutExtension + ".jpg";
            
            // If the xml file with metadata exists and it's not forced to reload, stop...
            if (!ForceReload && File.Exists(fileNameXML))
            {
                WriteLogging("[XML EXISTS] The xml file exists already for <" + file + ">");
                return;
            }

            // Prepare the search term for searching...
            string searchTerm = fileNameWithoutExtension.ToLowerInvariant();

            // If there are terms to exclude... exclude them...
            if(TermsToExclude != null)
            {
                foreach (string termToExclude in TermsToExclude)
                    searchTerm = searchTerm.Replace(termToExclude.ToLowerInvariant(), "");
            }
            
            // Else go look for the data, based on the specified sources to use...
            SearchMovieDbMetadata(searchTerm, fileNameXML, fileNameJPG, file);
            
            //SearchTvDbMetadata(searchTerm, fileNameXML, fileNameJPG, file);       
        }

        private bool SearchMovieDbMetadata(string searchTerm, string fileNameXML, string fileNameJPG, string fileNameFile)
        {
            searchTerm = searchTerm.ToLowerInvariant();
            
            TmdbAPI api = new TmdbAPI("ec8a279e97ba258e2782814d37fd84b7");
            TmdbMovie[] movies = api.MovieSearch(searchTerm);

            // If no result, no good :-(...
            if (movies.Length == 0)
            {
                WriteLogging("[NOT FOUND ] No metadata found in themoviedb.org for searchterm <" + searchTerm + "> for file <" + fileNameFile + ">");
                return false;
            }

            // If multiple results, we can't choose the right one automatically...
            if (movies.Length > 1)
            {
                WriteLogging("[TOO MANY  ] > 1 result in themoviedb.org for searchterm <" + searchTerm + "> for file <" + fileNameFile + ">");
                return false;
            }

            // If only one result... load all detailed info, and write to xml file...
            if (movies.Length == 1)
            {
                // Get the xml data...
                TmdbMovie movie = api.GetMovieInfo(movies[0].Id);
                WDTVLiveHubMetadata metadata = new WDTVLiveHubMetadata(movie);
                XmlSerializer serializer = new XmlSerializer(typeof(WDTVLiveHubMetadata));
                TextWriter writer = new StreamWriter(fileNameXML);
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "");         // empty namespace, otherwise he writes a default namespace...

                serializer.Serialize(writer, metadata, ns);
                writer.Close();

                WriteLogging("[XML OK    ] XML written from themoviedb.org for <" + fileNameFile + ">");

                // If at least one thumbnail is found... get the first one...
                if (metadata.Thumbnails.Count > 0)
                {
                    string thumbnailUrl = metadata.Thumbnails[0];

                    WebClient myWebClient = new WebClient();
                    byte[] data = myWebClient.DownloadData(thumbnailUrl);

                    System.IO.StreamWriter sw = new System.IO.StreamWriter(fileNameJPG);
                    System.IO.BinaryWriter bw = new System.IO.BinaryWriter(sw.BaseStream);
                    bw.Write(data);
                    bw.Close();

                    WriteLogging("[XML OK    ] JPG written from themoviedb.org for <" + fileNameFile + ">");
                }
            }

            return true;
        }


/*        private bool SearchTvDbMetadata(string searchTerm, string fileNameXML, string fileNameJPG, string fileNameFile)
        {
            // Maybe it is a TV series...
            // Load TV series data, for if it's a TV series
            TvdbHandler tvseries = new TvdbHandler(null, "7BEA0A77763E404B");
            List<TvdbSearchResult> res = tvseries.SearchSeries(searchTerm);

            // If no result, no good :-(...
            if (res.Count == 0)
            {
                WriteLogging("[NOT FOUND ] No metadata found in theTvDb.com for searchterm <" + searchTerm + "> for file <" + fileNameFile + ">");
                return false;
            }

            // If multiple results, we can't choose the right one automatically...
            if (res.Count > 1)
            {
                WriteLogging("[TOO MANY  ] > 1 result in theTvDb.com for searchterm <" + searchTerm + "> for file <" + fileNameFile + ">");
                return false;
            }

            // One result: OK!
            if (res.Count == 1)
            {
                // Load detailed data...
                TvdbSeries s = tvseries.GetSeries(res[0].Id, TvdbLanguage.DefaultLanguage, true, true, true, false);

                if (s != null)
                {
                    WDTVLiveHubMetadata metadata = new WDTVLiveHubMetadata(s);

                    XmlSerializer serializer = new XmlSerializer(typeof(WDTVLiveHubMetadata));
                    TextWriter writer = new StreamWriter(fileNameXML);
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", "");         // empty namespace, otherwise he writes a default namespace...

                    serializer.Serialize(writer, metadata, ns);
                    writer.Close();
                    WriteLogging("[OK        ] XML written from theTvDb.com for <" + fileNameFile + ">");

                    // If at least one thumbnail is found... get the first one...
                    if (metadata.Thumbnails.Count > 0)
                    {
                        string thumbnailUrl = metadata.Thumbnails[0];

                        WebClient myWebClient = new WebClient();
                        byte[] data = myWebClient.DownloadData(thumbnailUrl);

                        System.IO.StreamWriter sw = new System.IO.StreamWriter(fileNameJPG);
                        System.IO.BinaryWriter bw = new System.IO.BinaryWriter(sw.BaseStream);
                        bw.Write(data);
                        bw.Close();

                        WriteLogging("[OK        ] JPG written from theTvDb.com for <" + fileNameFile + ">");
                    }
                }
                else
                {
                    WriteLogging("[ERROR     ] Problem loading data from theTvDb.com for ID " + res[0].Id + " for file <" + fileNameFile + ">");
                    return false;
                }
            }
            return true;
        }                
*/
        private void WriteLogging(string text)
        {
            if (LoggingFile != null && LoggingFile != "")
            {
                using (StreamWriter fileLogging = new System.IO.StreamWriter(LoggingFile, true))
                {
                    fileLogging.WriteLine(text);
                }
            }
        }
    }
}
